<!doctype html>
<html>
  <head>
    <meta charset="utf-8">

    <title>Razdel — сегментация русскоязычного текста на токены и предложения</title>
    <meta name="title" content="Razdel — сегментация русскоязычного текста на токены и предложения">
    <meta property="og:title" content="Razdel — сегментация русскоязычного текста на токены и предложения">
    <meta property="twitter:title" content="Razdel — сегментация русскоязычного текста на токены и предложения">

    <meta name="description" content="Python-библиотека, часть проекта Natasha, система построена на правилах, высокое качество и скорость работы">
    <meta property="og:description" content="Python-библиотека, часть проекта Natasha, система построена на правилах, высокое качество и скорость работы">
    <meta property="twitter:description" content="Python-библиотека, часть проекта Natasha, система построена на правилах, высокое качество и скорость работы">

    <meta name="keywords" content="токены, предложения, токенизация, сегментация на предложения, русский язык, новости, tokenization, sentence boundaries">

    <meta property="og:type" content="website">
    <meta property="twitter:card" content="summary_large_image">

    <meta property="og:url" content="https://natasha.github.io/razdel/">
    <meta property="twitter:url" content="https://natasha.github.io/razdel/">

    <meta property="og:image" content="https://natasha.github.io/razdel/images/preview.png">
    <meta property="twitter:image" content="https://natasha.github.io/razdel/images/preview.png">

    <link rel="icon" href="/images/favicon.ico" type="image/x-icon">

    <link rel="stylesheet" href="/styles/bootstrap.min.css">
    <link rel="stylesheet" href="style.css">

    <!-- Google Tag Manager -->
    <script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
      new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
      j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
      'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
      })(window,document,'script','dataLayer','GTM-P65FXVJ');</script>
    <!-- End Google Tag Manager -->
  </head>
  <body>
    <!-- Google Tag Manager (noscript) -->
    <noscript><iframe src="https://www.googletagmanager.com/ns.html?id=GTM-P65FXVJ"
		      height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
    <!-- End Google Tag Manager (noscript) -->

    <div class="container">
      <div class="row">
      	<div class="col-8">
      	  <p>
      	    <a href="/">
      	      <span class="hanging-arrow">←</span> Проект Natasha
      	    </a>
      	  </p>

      	  <h1>Razdel — сегментация русскоязычного текста на токены и предложения</h1>
      	</div>
      </div>

      <div class="row">
      	<div class="col-6">
      	  <p>
	    <a href="https://github.com/natasha/razdel">Python-библиотека Razdel</a> — часть <a href="https://github.com/natasha">проекта Natasha</a>, делит русскоязычный текст на токены и предложения.
      	  </p>
	  <pre>
>>> from razdel import tokenize, sentenize

>>> text = 'Кружка-термос на 0.5л (50/64 см³, 516;...)'
>>> tokens = list(tokenize(text))
>>> tokens
[Substring(start=0, stop=13, text='Кружка-термос'),
 Substring(start=14, stop=16, text='на'),
 Substring(start=17, stop=20, text='0.5'),
 Substring(start=20, stop=21, text='л'),
 Substring(start=22, stop=23, text='(')
 ...]

>>> text = '''
... - "Так в чем же дело?" - "Не ра-ду-ют".
... И т. д. и т. п. В общем, вся газета
... '''
>>> list(sentenize(text))
[Substring(start=1, stop=23, text='- "Так в чем же дело?"'),
 Substring(start=24, stop=40, text='- "Не ра-ду-ют".'),
 Substring(start=41, stop=56, text='И т. д. и т. п.'),
 Substring(start=57, stop=76, text='В общем, вся газета')]</pre>
      	</div>
      </div>

      <div class="row">
	<div class="col-6">
	  <p>
	    Скорость и качество сопоставимы или выше, чем у других открытых решений.
	  </p>
	</div>
      </div>

      <div id="eval" class="row">
	<div class="col col-lg-4 col-md-5 col-sm-6">
	  <table id="token" class="table table-borderless">
      	    <thead>
      	      <tr>
      		<th></th>
      		<th scope="col">Ошибки на 1000 токенов</th>
      		<th scope="col">Время обработки, секунды</th>
      	      </tr>
      	    </thead>
      	    <tbody>
	      <tr>
		<th>Regexp-baseline</th>
		<td>19</td>
		<td><b>0.5</b></td>
	      </tr>
	      <tr>
		<th>
		  <a href="https://github.com/natasha/naeval#spacy">SpaCy</a>
		</th>
		<td>17</td>
		<td>5.4</td>
	      </tr>
	      <tr>
		<th>
		  <a href="https://github.com/natasha/naeval#nltk">NLTK</a>
		</th>
		<td>130</td>
		<td>3.1</td>
	      </tr>
	      <tr>
		<th>
		  <a href="https://github.com/natasha/naeval#mystem">MyStem</a>
		</th>
		<td>19</td>
		<td>4.5</td>
	      </tr>
	      <tr>
		<th>
		  <a href="https://github.com/natasha/naeval#moses">Moses</a>
		</th>
		<td><b>11</b></td>
		<td><b>1.9</b></td>
	      </tr>
	      <tr>
		<th>
		  <a href="https://github.com/natasha/naeval#segtok">SegTok</a>
		</th>
		<td>12</td>
		<td>2.1</td>
	      </tr>
	      <tr>
		<th>
		  <a href="https://github.com/natasha/naeval#spacy_russian_tokenizer">SpaCy Russian Tokenizer</a>
		</th>
		<td><b>8</b></td>
		<td>46.4</td>
	      </tr>
	      <tr>
		<th>
		  <a href="https://github.com/natasha/naeval#rutokenizer">RuTokenizer</a>
		</th>
		<td>15</td>
		<td><b>1.0</b></td>
	      </tr>
	      <tr>
		<th>
		  Razdel
		</th>
		<td><b>7</b></td>
		<td>2.6</td>
	      </tr>
	    </tbody>
	  </table>
	</div>

	<div class="col-lg-4 col-md-5 col-sm-6">
	  <table class="table table-borderless">
      	    <thead>
      	      <tr>
      		<th></th>
      		<th scope="col">Ошибки на 1000 предложений</th>
      		<th scope="col">Время обработки, секунды</th>
      	      </tr>
      	    </thead>
      	    <tbody>
	      <tr>
		<th>Regexp-baseline</th>
		<td>76</td>
		<td><b>0.7</b></td>
	      </tr>
	      <tr>
		<th>
		  <a href="https://github.com/natasha/naeval#segtok">SegTok</a>
		</th>
		<td>381</td>
		<td>10.8</td>
	      </tr>
	      <tr>
		<th>
		  <a href="https://github.com/natasha/naeval#moses">Moses</a>
		</th>
		<td>166</td>
		<td><b>7.0</b></td>
	      </tr>
	      <tr>
		<th>
		  <a href="https://github.com/natasha/naeval#nltk">NLTK</a>
		</th>
		<td><b>57</b></td>
		<td>7.1</td>
	      </tr>
	      <tr>
		<th>
		  <a href="https://github.com/natasha/naeval#rusenttokenizer">DeepPavlov</a>
		</th>
		<td><b>41</b></td>
		<td>8.5</td>
	      </tr>
	      <tr>
		<th>Razdel</th>
		<td><b>43</b></td>
		<td><b>4.8</b></td>
	      </tr>
	    </tbody>
	  </table>

	  <div class="note">
	    Число ошибок среднее по 4 датасетам: <a href="https://github.com/natasha/corus#load_ud_syntag">SynTagRus</a>, <a href="https://github.com/natasha/corus#load_morphoru_corpora">OpenCorpora</a>, <a href="https://github.com/natasha/corus#load_morphoru_gicrya">GICRYA</a> and <a href="https://github.com/natasha/corus#load_morphoru_rnc">RNC</a>. Подробнее в <a href="https://github.com/natasha/razdel#evaluation">репозитории Razdel</a>.
	  </div>

	</div>
      </div>

      <h2>В чём сложность?</h2>

      <div class="row">
	<div class="col-6">
	  <p>
	    В русском языке предложения обычно заканчиваются точкой, вопросительным или восклицательным знаком. Просто разделим текст регулярным выражением <code>[.?!]\s+</code>. Такое решение даст 76 ошибок на 1000 предложений.
	  </p>
	  <dl class="examples errors">
	    <dt>Сокращения.</dt>
	    <dd>
	      <p class="example partition">
		… любая площадка с аудиторией от 3 тыс.| |человек является блогером.
	      </p>
	      <p class="example partition">
		… над ними с конца XVII в.| |стоял бей;
	      </p>
	      <p class="example partition">
		… в Камерном музыкальном театре им.| |Б.А. Покровского.
	      </p>
	    </dd>

	    <dt>Инициалы.</dt>
	    <dd>
	      <p class="example partition">
	  	В след за операми «Идоменей» В.А.| |Моцарта – Р.| |Штрауса …
	      </p>
	    </dd>

	    <dt>Списки.</dt>
	    <dd>
	      <p class="example partition">
	  	2.| |думал будет в финское консульство красивая длинная очередь …
	      </p>
	      <p class="example partition">
	  	г.| |билеты на поезда российских железных дорог …
	      </p>
	    </dd>

	    <dt>В конце предложения многоточие, смайлик.</dt>
	    <dd>
	      <p class="example partition">
	  	Кто предложит способ избавления от минусов — тому спасибо :)| |Посмотрел, призадумался…| |Вот это уже более неприятно, поскольку содержательность нарушится.
	      </p>
	    <dd>

	    <dt>Цитаты, прямая речь, в конце предложения кавычка.</dt>
	    <dd>
	      <p class="example partition">
	  	— невесты у вас в городе есть?»| |«Кому и кобыла невеста».
	      </p>
	      <p class="example partition">
	  	«Как хорошо, что я не такой!»| |Сейчас при переводе сделал фрейдстскую ошибку:"идология".
	      </p>
	    </dd>

	  </dl>

	  <p>
	    Razdel учитывает эти нюансы, сокращает число ошибок до 43 на 1000 предложений.
	  </p>

	  <p>
	    С токенами аналогичная ситуация. Хорошее базовое решение даёт регулярное выражение <code>[а-яё-]+|[0-9]+|[^а-яё0-9 ]</code>, оно делает 19 ошибок на 1000 токенов.
	  </p>

	  <p class="example partition errors">
	    … В конце 1980|-х - начале 1990|-х
	    … БС-|3 можно отметить слегка меньшую массу (3|,|6 т)
	    — да и умерла.|.|. Понял ли девку, сокол?|!
	  </p>

	  <p>
	    Razdel сокращает число ошибок до 7 на 1000 токенов.
	  </p>

	</div>
      </div>

      <h2>Принцип работы</h2>

      <div class="row">
      	<div class="col-6">
      	  <p>
      	    Система построена на правилах. Принцип сегментации на токены и предложения одинаковый.
      	  </p>
      	</div>
      </div>

      <h3>Сбор кандидатов</h3>

      <div class="row">
      	<div class="col-6">
      	  <p>
      	    Находим в тексте всех кандидатов на конец предложения: точки, многоточия, скобки, кавычки.
      	  </p>

      	  <p class="example partition cands">
      	    6.| |Наиболее частый и при этом высоко оцененный вариант ответов «я рада»| |(13 высказываний, 25 баллов)| |– ситуации получения одобрения и поощрения.| |7.| |Примечательно, что в ответе «я знаю»| |оценен как максимально стереотипный, но лишь раз встречается ответ «я женщина»|;| |присутствуют высказывания «один брак – это всё, что меня ждет в этой жизни»| |и «рано или поздно придется рожать»|.| |Составители: В.| |П.| |Головин, Ф.| |В.| |Заничев, А.| |Л.| |Расторгуев, Р.| |В.| |Савко, И.| |И.| |Тучков.
      	  </p>

	  <p>
	    Для токенов дробим текст на атомы. Внутри атома точно не проходит граница токена.
	  </p>

      	  <p class="example partition cands">
	    В| |конце| |1980|-|х| |-| |начале| |1990|-|х|
	    БС|-|3| |можно| |отметить| |слегка| |меньшую| |массу| |(|3|,|6| |т|)|
	    |—| |да| |и| |умерла|.|.|.| |Понял| |ли| |девку|,| |сокол|?|!
	  </p>

      	</div>
      </div>

      <h3>Объединение</h3>

      <div class="row">
      	<div class="col-6">
      	  <p>
      	    Последовательно обходим кандидатов на разделение, убираем лишние. Используем список эвристик.
      	  </p>

      	  <dl class="examples">
      	    <dt>
      	      Элемент списка. Разделитель — точка или скобка, слева число или буква.
      	    </dt>
      	    <dd>
      	      <p class="example partition joins">
      		6.| |Наиболее частый и при этом высоко оцененный вариант ответов «я рада» (13 высказываний, 25 баллов) – ситуации получения одобрения и поощрения. 7.| |Примечательно, что в ответе «я знаю» …
      	      </p>
      	    </dd>

      	    <dt>
      	      Инициалы. Разделитель — точка, слева одна заглавная буква.
      	    </dt>
      	    <dd>
      	      <p class="example partition joins">
		… Составители: В.| |П.| |Головин, Ф.| |В.| |Заничев, А.| |Л.| |Расторгуев, Р.| |В.| |Савко, И.| |И.| |Тучков.
	      </p>
      	    </dd>

      	    <dt>
      	      Справа от разделителя нет пробела.
      	    </dt>
      	    <dd>
      	      <p class="example partition joins">
      		… но лишь раз встречается ответ «я женщина»|; присутствуют высказывания «один брак – это всё, что меня ждет в этой жизни» и «рано или поздно придется рожать»|.
	      </p>
      	    </dd>

      	    <dt>
      	      Перед закрывающей кавычкой или скобкой нет знака конца предложения, это не цитата и не прямая речь.
      	    </dt>
      	    <dd>
      	      <p class="example partition joins">
      		6. Наиболее частый и при этом высоко оцененный вариант ответов «я рада»| |(13 высказываний, 25 баллов)| |– ситуации получения одобрения и поощрения. … «один брак – это всё, что меня ждет в этой жизни»| |и «рано или поздно придется рожать».
	      </p>
      	    </dd>
      	  </dl>

	  <p>
	    В результате остаётся два разделителя, считаем их концами предложений.
	  </p>

	  <p class="example partition cands">
	    6. Наиболее частый и при этом высоко оцененный вариант ответов «я рада» (13 высказываний, 25 баллов) – ситуации получения одобрения и поощрения.| |7. Примечательно, что в ответе «я знаю» оценен как максимально стереотипный, но лишь раз встречается ответ «я женщина»; присутствуют высказывания «один брак – это всё, что меня ждет в этой жизни» и «рано или поздно придется рожать».| |Составители: В. П. Головин, Ф. В. Заничев, А. Л. Расторгуев, Р. В. Савко, И. И. Тучков.
	  </p>

      	  <p>
      	    Для токенов процедура аналогичная, правила другие.
      	  </p>

      	  <dl class="examples">
      	    <dt>
      	      Дробь или рациональное число.
      	    </dt>
      	    <dd>
      	      <p class="example partition joins">
		… (3|,|6 т) …
      	      </p>
      	    </dd>

      	    <dt>
      	      Сложная пунктуация.
      	    </dt>
      	    <dd>
      	      <p class="example partition joins">
		— да и умерла.|.|. Понял ли девку, сокол?|!
      	      </p>
      	    </dd>

      	    <dt>
      	      Вокруг дефиса нет пробелов, это не начало прямой речи.
      	    </dt>
      	    <dd>
      	      <p class="example partition joins">
		В конце 1980|-|х - начале 1990|-|х
		БС|-|3 можно отметить …
      	      </p>
      	    </dd>

	  </dl>

	  <p>
	    Всё что осталось считаем границами токенов.
      	      <p class="example partition cands">
		В| |конце| |1980-х| |-| |начале| |1990-х|
		БС-3| |можно| |отметить| |слегка| |меньшую| |массу| |(|3,6| |т|)|
		|—| |да| |и| |умерла|...| |Понял| |ли| |девку|,| |сокол|?!
      	      </p>
	  </p>
	  
      	</div>
      </div>

      <h2>Ограничения</h2>

      <div class="row">
	<div class="col-6">
	  <p>
	    Правила в Razdel оптимизированы для аккуратно написанных текстов с правильной пунктуацией. Решение хорошо работает с новостными статьями, художественными текстами. На постах из социальных сетей, расшифровках телефонных разговоров качество ниже.
	  </p>
	  <p>
	    Если между предложениями нет пробела или в конце нет точки или предложение начинается с маленькой буквы, Razdel сделает ошибку.
	  </p>
	</div>
      </div>

      <h2>Использование</h2>

      <div class="row">
	<div class="col-6">
	  <p>
	    <a href="https://github.com/natasha/razdel#installation">Инструкция по установке</a>, <a href="https://github.com/natasha/razdel#usage">пример использования</a> и <a href="https://github.com/natasha/razdel#evaluation">замеры производительности</a> — в <a href="https://github.com/natasha/razdel">репозитории Razdel</a>.
	  </p>

	  <p>
	    <a href="https://t.me/natural_language_processing"><img class="inline" src="/images/social/tg.svg" /> natural_language_processing</a> — чат пользователей, разработчиков проекта.
	  </p>

	</div>
      </div>

      <div id="footer">
	<div class="row">
      	  <div class="col-2">
      	    <img src="/images/author.jpg" class="rounded img-fluid" alt="Александр Кукушкин">
      	  </div>
      	  <div class="col-4">
      	    Александр Кукушкин, август 2020 года
      	    <ul>
      	      <li>
		<a href="mailto:alex@alexkuk.ru">alex@alexkuk.ru</a>
	      </li>

      	      <li>
		<a href="https://t.me/alexkuk">
		  <img class="inline" src="/images/social/tg.svg" /> alexkuk
		</a>
	      </li>

      	      <li>
		<a href="https://github.com/kuk">
		  <img class="inline" src="/images/social/gh.svg" /> kuk
		</a>
	      </li>
      	    </ul>

	    <a href="https://lab.alexkuk.ru/">Лаборатория анализа данных Александра Кукушкина</a>
	      <p>
		Лаборатория разрабатывает сервисы и коробочные продукты с использованием технологии Natasha, оказывает услуги анализа данных для российских компаний.
	      </p>

	  </div>
	</div>
      </div>


    </div>

    <script src="/scripts/jquery-3.5.1.min.js" type="text/javascript"></script>
    <script src="/scripts/popper.min.js" type="text/javascript"></script>
    <script src="/scripts/bootstrap.min.js" type="text/javascript"></script>
    <script src="script.js" type="text/javascript"></script>
  </body>
</html>
